package com.yuke.cloud.service.cmc.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yuke.cloud.common.core.support.BaseService;
import com.yuke.cloud.common.util.DateUtil;
import com.yuke.cloud.common.util.wrapper.Wrapper;
import com.yuke.cloud.service.api.wmc.service.WmcStorageFeignApi;
import com.yuke.cloud.service.cmc.dao.CmsRedReceiveMapper;
import com.yuke.cloud.service.cmc.dto.CmsRedReceiveDto;
import com.yuke.cloud.service.cmc.entity.CmsCoupon;
import com.yuke.cloud.service.cmc.entity.CmsRedReceive;
import com.yuke.cloud.service.cmc.entity.CmsSysInfo;
import com.yuke.cloud.service.cmc.service.CmsCouponService;
import com.yuke.cloud.service.cmc.service.CmsRedReceiveService;
import com.yuke.cloud.service.cmc.service.CmsSysInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.yuke.cloud.common.util.DateUtil.*;


/**
 * Created by zn on 2020/09/19.
 */
@Service
@Transactional
public class CmsRedReceiveServiceImpl extends BaseService<CmsRedReceive> implements CmsRedReceiveService {
    @Resource
    private CmsRedReceiveMapper cmsRedReceiveMapper;
    @Resource
    private CmsCouponService cmsCouponService;
    @Resource
    private WmcStorageFeignApi wmcStorageFeignApi;
    @Resource
    private CmsSysInfoService cmsSysInfoService;
    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public Integer checkRedReceive(Long userId){
        String  todayTime = getStringDate(todayTimeBegin());
        String  nextTime = getStringDate(nextDayTimeBegin());

        Example example = new Example(CmsRedReceive.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId",userId);
        criteria.andCondition("add_time >='"+ todayTime + "' and add_time < '" + nextTime+"'");

        Integer num = cmsRedReceiveMapper.selectCountByExample(example);

        return num;
    }

    @Override
    public Integer saveRedReceive(CmsRedReceive cmsRedReceive){
        Date nowDate = new Date();
        CmsCoupon cmsCoupon = cmsCouponService.findById(cmsRedReceive.getCouponId());
        if (cmsCoupon == null || cmsCoupon.getSendEndDate().getTime() < nowDate.getTime()){
            return 0;
        }
        //获取红包金额限制信息
        Example example = new Example(CmsSysInfo.class);
        Example.Criteria criteria = example.createCriteria();
        Long shopGroupId = cmsRedReceive.getGroupId();
        criteria.andEqualTo("sysInfoType", 20);
        if (shopGroupId == null || shopGroupId < 1) {
            Long shopId = cmsRedReceive.getShopId();
            Wrapper wrap = wmcStorageFeignApi.getGroupIdByShopId(shopId);
            if (wrap.getCode() == 200 && wrap.getResult() != null) {
                shopGroupId = Long.valueOf(wrap.getResult().toString());
            } else {
                shopGroupId = 220839532667469824L;
            }
            criteria.andEqualTo("groupId", shopGroupId);
        }

        List<CmsSysInfo> cmsSysInfoList = cmsSysInfoService.selectByExample(example);
        Integer minLow = 50;
        Integer minHigh = 100;
        Integer maxLow = 100;
        Integer maxHigh = 200;
        Integer typeMoney = 0;
        if (cmsSysInfoList != null && cmsSysInfoList.size() > 0) {
            //获得随机红包标准
            CmsSysInfo cmsSysInfo = cmsSysInfoList.get(0);
            if (cmsSysInfo != null && cmsSysInfo.getStatus() > 0) {
                JSONObject jsonObject = JSON.parseObject(cmsSysInfo.getInfoValue());
                System.out.println(jsonObject);
                minLow = jsonObject.getInteger("minLow");
                minHigh = jsonObject.getInteger("minHigh");
                maxLow =  jsonObject.getInteger("maxLow");
                maxHigh = jsonObject.getInteger("maxHigh");
            }
        }

        //获取随机数
        if (cmsRedReceive.getRedTag().equals((byte)0)){
            long randomNum = System.currentTimeMillis();
            typeMoney = (int) (randomNum % (minHigh-minLow)+minLow);

        }
        if (cmsRedReceive.getRedTag().equals((byte)1)){
            long randomNum = System.currentTimeMillis();
            typeMoney = (int) (randomNum % (maxHigh-maxLow)+maxLow);

        }
        if (typeMoney.intValue() == 0){
            return typeMoney;
        }

        Long expireTime = 0L;
        if (cmsRedReceive.getRedValidity() != null){
            //根据redValidity指定的天数
            if (cmsRedReceive.getRedValidity() > 0){
                expireTime = 3600 * 24 * Long.valueOf(cmsRedReceive.getRedValidity().toString())
                         - 3600;
            }
            //当天有效
            if (cmsRedReceive.getRedValidity() < 0){
                expireTime = (getDateTimeEnd(nowDate).getTime() - (new Date()).getTime()) - 3600;
            }
            //根据优惠券指定时间
            if (cmsRedReceive.getRedValidity().equals((byte)0) ){
                expireTime = cmsCoupon.getUseEndDate().getTime() - (new Date()).getTime() - 3600;
            }

        }else{ //如果没有指定，默认为24小时
            expireTime = 3600 * 23L;
            cmsRedReceive.setRedValidity((byte)1);
        }

        cmsRedReceive.setRedReceiveId(generateId());
        cmsRedReceive.setTypeMoney(typeMoney.toString());
        cmsRedReceive.setRedStatus((byte)0);

        cmsRedReceive.setRedValidity((byte)1);
        cmsRedReceive.setAddTime(nowDate);
        Integer num = cmsRedReceiveMapper.insertSelective(cmsRedReceive);

        //保存redis，过期前提醒提前1个小时提醒
        if (num > 0 && expireTime > 0 ){
            String id = "redReceive:" + cmsRedReceive.getRedReceiveId();
            System.out.println("redis存入的key："+id);
            redisTemplate.opsForValue().set(id, "红包过期提醒", expireTime, TimeUnit.SECONDS);
        }

        return typeMoney;
    }

    @Override
    public List<CmsRedReceiveDto> getRedReceive(Long userId){
        //获取最近7天的打卡信息，userId，随机签到红包45
        String  todayTime = getStringDate(DateUtil.nextDayTimeBegin());
        String sevenTime = getStringDate(numDayTimeBegin(6));

        Example example = new Example(CmsRedReceive.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId",userId);
        criteria.andEqualTo("receiveType",2);
        criteria.andEqualTo("couponId",45);
        criteria.andCondition("add_time >='"+ sevenTime + "' and add_time < '" + todayTime+"'");
        example.setOrderByClause("add_time asc");
        List<CmsRedReceive> cmsRedReceiveList = cmsRedReceiveMapper.selectByExample(example);

        if (cmsRedReceiveList == null || cmsRedReceiveList.size() < 1){
            return null;
        }

        List<CmsRedReceiveDto> redReceiveDtoList = new ArrayList<>();
        Date addTime = cmsRedReceiveList.get(0).getAddTime();
        int jiange = 0;
        for (CmsRedReceive cmsRedReceive : cmsRedReceiveList){
            //拿到大红包，要重新开始记录,当前记录不保存.但是今天领的大红包要保留，显示用。
            if (cmsRedReceive.getRedTag().equals((byte)1) && cmsRedReceive.getAddTime().getTime() < todayTimeBegin().getTime()){
                redReceiveDtoList.clear();
                addTime = cmsRedReceive.getAddTime();
                jiange = 0;
                continue;
            }
            // 间隔天数>3,要重新开始记录，保存当前记录
            System.out.println("间隔天数:"+differentDays(addTime,cmsRedReceive.getAddTime()));
            if (differentDays(addTime,cmsRedReceive.getAddTime()) > 3){
                redReceiveDtoList.clear();
                addTime = cmsRedReceive.getAddTime();
                jiange = 0;
            }
            //合计间隔天数》2，去除第一条记录
            if (differentDays(addTime,cmsRedReceive.getAddTime()) >1){
                jiange += differentDays(addTime,cmsRedReceive.getAddTime())-1;
            }

            //今天之前的记录满5条，删除第一条
            if (redReceiveDtoList.size() > 4 && cmsRedReceive.getAddTime().getTime() < todayTimeBegin().getTime()){
                redReceiveDtoList.remove(0);
            }
            addTime = cmsRedReceive.getAddTime();
            // 判断红包状态是否过期
            Long addtime = addTime.getTime()+24*60*60*1000;
            if (System.currentTimeMillis() > addtime && cmsRedReceive.getRedStatus() < 1){
                cmsRedReceive.setRedStatus((byte)2);
                this.update(cmsRedReceive);
            }
            CmsRedReceiveDto cmsRedReceiveDto = new CmsRedReceiveDto();
            BeanUtils.copyProperties(cmsRedReceive ,cmsRedReceiveDto);


            redReceiveDtoList.add(cmsRedReceiveDto);
        }
        if (differentDays(addTime,new Date()) > 3){
            redReceiveDtoList.clear();
        }
        System.out.println("合计间隔天数："+jiange);
        if (jiange > 2 && redReceiveDtoList.size() > 1){
            redReceiveDtoList.remove(0);
        }
        return redReceiveDtoList;
    }

    @Override
    public List selectRedReceiveByCondition(CmsRedReceiveDto cmsRedReceiveDto) {
        if (cmsRedReceiveDto.getBeginTime() == null && cmsRedReceiveDto.getEndTime() == null){
            cmsRedReceiveDto.setBeginTime(lastMonthTimeBegin());
            cmsRedReceiveDto.setEndTime(new Date());
        }
        List<CmsRedReceiveDto> cmsRedReceiveDtoList = cmsRedReceiveMapper.selectRedReceiveByCondition(cmsRedReceiveDto);
        if (cmsRedReceiveDtoList != null && cmsRedReceiveDtoList.size() > 0){
            for (CmsRedReceiveDto cmsRedReceive : cmsRedReceiveDtoList){
                Long addtime = cmsRedReceive.getAddTime().getTime()+24*60*60*1000;

                if (System.currentTimeMillis() > addtime && cmsRedReceive.getRedStatus().equals((byte)0)){

                    updateRedReceiveExpire(cmsRedReceive.getRedReceiveId());
                }
            }

        }
        return cmsRedReceiveDtoList;
    }

    @Override
    public  Integer updateRedReceiveExpire(Long redReceiveId){
        CmsRedReceive cmsRedReceive = new CmsRedReceive();
        cmsRedReceive.setRedReceiveId(redReceiveId);
        cmsRedReceive.setRedStatus((byte)2);
        return cmsRedReceiveMapper.updateByPrimaryKeySelective(cmsRedReceive);
    }

    @Override
    public  Integer updateRedReceiveUsered(Long redReceiveId, String orderIds){

        CmsRedReceive cmsRedReceive = super.findById(redReceiveId);

        String id = "redReceive:" + redReceiveId;
        redisTemplate.delete(id);

        cmsRedReceive.setRedStatus((byte)1);
        cmsRedReceive.setOrderId(orderIds);
        cmsRedReceive.setUsedTime(new Date());
        return cmsRedReceiveMapper.updateByPrimaryKeySelective(cmsRedReceive);
    }
}
